package com.wnzt.baszh.util.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.pdfbox.io.RandomAccessBuffer;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.xml.security.utils.Base64;

public class PdfParser {

	/**
	 * 解析
	 * @author [lv tang wei]
	 * Describe:
	 * @param filebyte
	 * @return
	 * [2017年7月18日]
	 * @throws Exception 
	 */
	public static Map<String,Object> parser(String filepath) throws Exception{
		//System.out.println("开始解析...");
		Map<String,Object> map=new HashMap<String,Object>();
		map=parserInfo(filepath);
        PDDocument document = null;
        try{
            // 方式一：
            InputStream input = null;
            input = new FileInputStream(new File(filepath));
            //加载 pdf 文档
            PDFParser parser = new PDFParser(new RandomAccessBuffer(input));
            parser.parse();
            document = parser.getPDDocument();

            // 方式二：
            //document=PDDocument.load(pdfFile);

            // 获取页码
            int pages = document.getNumberOfPages();
            
            // 读文本内容
            PDFTextStripper stripper=new PDFTextStripper();
            // 设置按顺序输出
            stripper.setSortByPosition(true);
            stripper.setStartPage(1);
            stripper.setEndPage(1);
            String content = stripper.getText(document);
            Pattern p = Pattern.compile("\\s+");
            Matcher m = p.matcher(content);
            content= m.replaceAll("");
            //System.out.println(content);
            if(content.indexOf("江门市新会区妇幼保健院妇科护理记录单")!=-1){//新会护理记录
            	map.put("filename", "新会护理记录");
            }else if(content.indexOf("24小时内入出院记录")!=-1){//24小时内入出院记录
            	map.put("filename", "24小时内入出院记录");
            }else if(content.indexOf("24小时死亡记")!=-1){//24小时死亡记录
            	map.put("filename", "24小时死亡记录");
            }else if(content.indexOf("临时医嘱单")!=-1){//临时医嘱单
            	map.put("filename", "临时医嘱单");
            }else if(content.indexOf("妇科入院评估护理记录")!=-1){//入院护理评估单
            	map.put("filename", "入院护理评估单");
            }else if(content.indexOf("入院病情告知谈话记录")!=-1){//入院病情告知记录
            	map.put("filename", "入院病情告知记录");
            }else if(content.indexOf("入院记录(2)")!=-1){//入院记录二
            	map.put("filename", "入院记录二");
            }else if(content.indexOf("入院记录")!=-1 && content.indexOf("入院记录(2)")==-1){//入院记录
            	map.put("filename", "入院记录");
            }else if(content.indexOf("患者授权委托书")!=-1){//患者授权委托书
            	map.put("filename", "患者授权委托书");
            }else if(content.indexOf("手术同意书")!=-1){//手术同意书
            	map.put("filename", "手术同意书");
            }else if(content.indexOf("手术记录")!=-1){//手术记录
            	map.put("filename", "手术记录");
            }else if(content.indexOf("拒绝医疗告知书")!=-1){//拒绝医疗告知书
            	map.put("filename", "拒绝医疗告知书");
            }else if(content.indexOf("术前核对单")!=-1){//术前核对单
            	map.put("filename", "术前核对单");
            }else if(content.indexOf("特殊检查、特殊治疗知情同意书")!=-1){//特殊治疗同意书
            	map.put("filename", "特殊治疗同意书");
            }else if(content.indexOf("病情危（重）通知书")!=-1){//病危通知单
            	map.put("filename", "病危通知单");
            }else if(content.indexOf("病理活体组织送验单")!=-1){//病理活体组织送验单
            	map.put("filename", "病理活体组织送验单");
            }else if(content.indexOf("病史确认书")!=-1){//病史确认书
            	map.put("filename", "病史确认书");
            }else if(content.indexOf("病案号：麻醉切口")!=-1){//病案首页续页
            	map.put("filename", "病案首页续页");
            }else if(content.indexOf("病案首页")!=-1){//病案首页
            	map.put("filename", "病案首页");
            }else if(content.indexOf("输血治疗同意书")!=-1){//输血治疗同意书
            	map.put("filename", "输血治疗同意书");
            }else if(content.indexOf("长期医嘱单")!=-1){//长期医嘱单
            	map.put("filename", "长期医嘱单");
            }else if(content.indexOf("麻醉知情同意书")!=-1){//麻醉知情同意书
            	map.put("filename", "麻醉知情同意书");
            }else if(content.indexOf("会诊记录")!=-1){//会诊记录
            	map.put("filename", "会诊记录");
            }else if(content.indexOf("会诊邀请函")!=-1){//会诊邀请函
            	map.put("filename", "会诊邀请函");
            }else if(content.indexOf("出院记录")!=-1){//出院记录
            	map.put("filename", "出院记录");
            }else if(content.indexOf("化疗记录表")!=-1){//化疗记录
            	map.put("filename", "化疗记录");
            }else if(content.indexOf("吸氧告知书")!=-1){//吸氧告知书
            	map.put("filename", "吸氧告知书");
            }else if(content.indexOf("妇科手术替代方案")!=-1){//妇科手术替代方案
            	map.put("filename", "妇科手术替代方案");
            }else if(content.indexOf("手术安全核查表")!=-1){//手术安全核查表
            	map.put("filename", "手术安全核查表");
            }else if(content.indexOf("手术护理记录单")!=-1){//手术护理记录单
            	map.put("filename", "手术护理记录单");
            }else if(content.indexOf("护理文书质量持续改进评分表科室")!=-1){//护理文书
            	map.put("filename", "护理文书");
            }else if(content.indexOf("护理文书质量持续改进评分表姓名")!=-1){//护理文书质量持续改进表
            	map.put("filename", "护理文书质量持续改进表");
            }else if(content.indexOf("儿科护理记录单")!=-1){//护理记录单（旧）
            	map.put("filename", "护理记录单（旧）");
            }else if(content.indexOf("新生儿科入院评估护理记录")!=-1){//新生儿入院评估单
            	map.put("filename", "新生儿入院评估单");
            }else if(content.indexOf("死亡病例讨论记录")!=-1){//死亡病历讨论记录
            	map.put("filename", "死亡病历讨论记录");
            }else if(content.indexOf("死亡记录")!=-1){//死亡记录
            	map.put("filename", "死亡记录");
            }else if(content.indexOf("特殊手术报告审批表")!=-1){//特殊手术报告审批表
            	map.put("filename", "特殊手术报告审批表");
            }else if(content.indexOf("疾病诊断证明书")!=-1){//疾病诊断证明书
            	map.put("filename", "疾病诊断证明书");
            }else if(content.indexOf("病历质量评分表")!=-1){//病历质量评分表
            	map.put("filename", "病历质量评分表");
            }else if(content.indexOf("病情告知谈话记录")!=-1){//病情告知谈话记录
            	map.put("filename", "病情告知谈话记录");
            }else if(content.indexOf("转科记录")!=-1){//转科记录
            	map.put("filename", "转科记录");
            }else if(content.indexOf("儿科首次护理记录")!=-1){//首次护理记录单
            	map.put("filename", "首次护理记录单");
            }else if(content.indexOf("体温单")!=-1){//三测单
            	map.put("filename", "三测单");
            }else if(content.indexOf("江门市新会区妇幼保健院首次病程记录")!=-1){//首次病程记录
            	map.put("filename", "首次病程记录");
            }else if(content.indexOf("出院病程记录")!=-1){//出院病程记录
            	map.put("filename", "出院病程记录");
            }else if(content.indexOf("病程记录")!=-1){//病程记录
            	map.put("filename", "病程记录");
            }else if(content.indexOf("产前入院评估护理记录")!=-1){//产前入院评估护理记录
            	map.put("filename", "产前入院评估护理记录");
            }else if(content.indexOf("产前待产记录")!=-1){//产前待产记录
            	map.put("filename", "产前待产记录");
            }else if(content.indexOf("产后护理记录")!=-1){//剖宫产产后护理记录
            	map.put("filename", "剖宫产产后护理记录");//---
            }else if(content.indexOf("引产记录表")!=-1){//引产记录表
            	map.put("filename", "引产记录表");
            }else if(content.indexOf("有创诊疗操作记录")!=-1){//有创诊疗操作记录
            	map.put("filename", "有创诊疗操作记录");
            }else if(content.indexOf("输血安全护理单")!=-1){//输血安全护理单
            	map.put("filename", "输血安全护理单");
            }else if(content.indexOf("产后护理记录")!=-1){//顺产产后护理记录
            	map.put("filename", "顺产产后护理记录");//---
            }
            
            System.out.println("filename:"+map.get("filename"));
            if(!GlobalFun.hasValue(map.get("filename"))){
            	System.out.println(content);
            }
        }catch(Exception e){
            throw new Exception("解析错误。");
        }
        //System.out.println("结束解析...");
		return map;
	}
	
	public static Map<String,Object> parserInfo(String filepath) throws Exception{
		Map<String,Object> info=new HashMap<String,Object>();
		File file=new File(filepath);
		FileUtil.createMultilayerFile("D:/pdftotxt");
		String txtfile="D:/pdftotxt/"+file.getName().substring(0,file.getName().lastIndexOf("."))+".txt";
		try {
			FileUtil.createFile(txtfile);
			pdf2text(file.getPath(),txtfile);
			String content=convertFileToString(txtfile);
			Pattern p = Pattern.compile("\\s+");
	        Matcher m = p.matcher(content);
	        content= m.replaceAll("");//变成一行字符串
	        content=content.replaceAll("：", "");
	        content=content.replaceAll(":", "");
	        String zyid=null;//住院号
	        String prn=null;//病案号
	        String times=null;//住院次数
	        if(content.indexOf("住院号")!=-1){//判断是否存在住院号
	        	zyid=content.substring(content.indexOf("住院号")+3,content.indexOf("住院号")+9);
	        	if(!isNumeric(zyid)){
	        		zyid=null;
	        	}else{
	        		info.put("zyid", zyid);
	        	}
	        }
	        if(zyid==null){//没有住院号取病案号
	        	if(content.indexOf("病案号")!=-1){//判断是否存在住院号
	        		prn=content.substring(content.indexOf("病案号")+3,content.indexOf("病案号")+9);
	            	if(!isNumeric(prn)){
	            		prn=null;
	            	}else{
		        		info.put("prn", prn);
		        	}
	            }
	        }
	        if(prn!=null){//有病案号再取住院次数
	        	if(content.indexOf("次住院")!=-1){//判断是否存在住院号
	        		times=content.substring(content.indexOf("次住院")-1,content.indexOf("次住院"));
	            	if(!isNumeric(times)){
	            		times=null;
	            	}else{
		        		info.put("times", times);
		        	}
	            }
	        }
	        if(zyid == null && (prn==null || times==null)){//解析失败
	        	System.out.println("解析失败:"+txtfile+"|"+content);
	        	FileUtil.deleteFile(txtfile);
	        	throw new Exception("解析失败，没有检测到住院号或病案号与住院次数!");
	        }
	        FileUtil.deleteFile(txtfile);
		} catch (Exception e) {
			e.printStackTrace();
			FileUtil.deleteFile(txtfile);
			throw new Exception(e.getMessage());
		}
        return info;
	}
	
	/**
	 * @param args
	 */
	public static void pdf2text(String pdffile, String txtfile)
			throws IOException {

		String pdfname = pdffile;
		String txtname = txtfile;
		String xpdfpath = "D:\\xpdf\\";
		String[] cmd = new String[] { xpdfpath + "pdftotext", "-layout",
				"-enc", "UTF-8", "-nopgbrk", pdfname, txtname };
		// -layout表示保持原有的layout，enc指定字符集，-nopgbrk指定不分页
		Process p = Runtime.getRuntime().exec(cmd);
		//d:\xpdf>pdftotext.exe  -enc GBK d:/xpdf/pdf/病程记录.pdf d:/xpdf/txt/病程记录.tx
	}

	public static void main(String[] args) {
		
		List<File> filelist=new ArrayList<File>();
		filelist=PdfParser.getFileList(filelist,"E:\\pdf2");
		for (File file : filelist) {
			try {
				System.out.println(file.getName());
				parser(file.getPath());
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static String convertFileToString(String filepath) throws FileNotFoundException {
		InputStream inputStream=new FileInputStream(new File(filepath));
	    BufferedReader reader = new BufferedReader(new InputStreamReader(
	            inputStream));
	    StringBuilder stringBuilder = new StringBuilder();
	 
	    try {
	        for (String line = reader.readLine(); line != null; line = reader
	                .readLine()) {
	            stringBuilder.append(line + "\n");
	        }
	        inputStream.close();
	        return stringBuilder.toString();
	    } catch (IOException e) {
	        throw new RuntimeException(e);
	    }
	}

	
	public static List<File> getFileList(List<File> filelist,String strPath) {
        File dir = new File(strPath);
        File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String fileName = files[i].getName();
                if (files[i].isDirectory()) { // 判断是文件还是文件夹
                    getFileList(filelist,files[i].getAbsolutePath()); // 获取文件绝对路径
                } else if (fileName.endsWith("pdf")) { // 判断文件名是否以.avi结尾
                    String strFileName = files[i].getAbsolutePath();
                    System.out.println("---" + strFileName);
                    filelist.add(files[i]);
                } else {
                    continue;
                }
            }

        }
        return filelist;
    }
	

	/**
	 * @author [lv tang wei]
	 * Describe:读取文件用Base64将其转化为字符串
	 * @param file
	 * @return
	 * @throws Exception
	 * [2017年5月24日]
	 */
	private static String getFileByteString(File file) throws Exception{
	    InputStream in = new FileInputStream(file);
	    // 取得文件大小
	    long length = file.length();
	    // 根据大小创建字节数组
	    byte[] bytes = new byte[(int) length];
	    // 读取文件内容到字节数组
	    int offset = 0;
	    int numRead = 0;
	    while (offset < bytes.length
	        && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) {
	      offset += numRead;
	    }
	    // 读取完毕的校验  
	    if (offset < bytes.length) {
	    	throw new IOException("不能完全读取文件："+ file.getName());
	    }
	    in.close();
	    String encodedFileString = Base64.encode(bytes);
	    return encodedFileString;
	}
	
	/**
     * 利用正则表达式判断字符串是否是数字
     * @param str
     * @return
     */
    public static boolean isNumeric(String str){
           Pattern pattern = Pattern.compile("[0-9]*");
           Matcher isNum = pattern.matcher(str);
           if( !isNum.matches() ){
               return false;
           }
           return true;
    }
}
